//
//  SortableController+AutoScroll.swift
//
//  Created by 谢强 on 16/03/2018.
//  Copyright © 2018 谢强. All rights reserved.
//

import UIKit

private let autoScroll_velocity_threshold:  CGFloat = 30
private let autoScroll_velocity_min:        CGFloat = 60
private let autoScroll_velocity_max:        CGFloat = 280

// TODO: - <TODO>
private func mapValue(
    _ value: CGFloat,
    inRangeWithMin minA: CGFloat,
    max maxA: CGFloat,
    toRangeWithMin minB: CGFloat,
    max maxB: CGFloat) -> CGFloat {
    return (value - minA) * (maxB - minB) / (maxA - minA) + minB
}

// MARK: - 底部滚动
extension SortableController {
    
    /// 滚动_开始
    func autoScroll_active() {
        autoScroll_displayLink = CADisplayLink(target: self, selector: #selector(handleDisplayLinkUpdate))
        autoScroll_displayLink?.add(to: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode)
        autoScroll_lastTImeStap = nil
    }
    
    /// 滚动_关闭
    func autoScroll_clear() {
        autoScroll_displayLink?.invalidate()
        autoScroll_displayLink = nil
        autoScroll_lastTImeStap = nil
    }
    
    /// 滚动_速度
    func autoScroll_velocity() -> CGFloat {
        
        guard let tableView = tableView, let snapshotView = snapshotView else { return 0 }
        
        guard autoScroll_enable else { return 0 }
        
        let safeAreaFrame: CGRect
        if #available(iOS 11, *) {
            safeAreaFrame = UIEdgeInsetsInsetRect(tableView.frame, tableView.safeAreaInsets)
        } else {
            safeAreaFrame = UIEdgeInsetsInsetRect(tableView.frame, tableView.scrollIndicatorInsets)
        }
        
        let distanceToTop = max(snapshotView.frame.minY - safeAreaFrame.minY, 0)
        let distanceToBottom = max(safeAreaFrame.maxY - snapshotView.frame.maxY, 0)
        
        if distanceToTop < autoScroll_velocity_threshold {
            return mapValue(
                distanceToTop,
                inRangeWithMin: autoScroll_velocity_threshold,
                max: 0, toRangeWithMin: -autoScroll_velocity_min,
                max: -autoScroll_velocity_max
            )
        }
        if distanceToBottom < autoScroll_velocity_threshold {
            return mapValue(distanceToBottom, inRangeWithMin: autoScroll_velocity_threshold, max: 0, toRangeWithMin: autoScroll_velocity_min, max: autoScroll_velocity_max)
        }
        return 0
    }
    
}

extension SortableController {
    
    @objc fileprivate func handleDisplayLinkUpdate(_ displayLink: CADisplayLink) {
        
        guard let tableView = tableView else { return }
        
        if let autoScroll_lastTImeStap = autoScroll_lastTImeStap {
            let velocity = autoScroll_velocity()
            
            if velocity != 0 {
                let elapsedTime = displayLink.timestamp - autoScroll_lastTImeStap
                let scrollDelta = CGFloat(elapsedTime) * velocity
                
                let contentOffset = tableView.contentOffset
                tableView.contentOffset = CGPoint(x: contentOffset.x, y: contentOffset.y + CGFloat(scrollDelta))
                
                let contentInset: UIEdgeInsets
                if #available(iOS 11, *) {
                    contentInset = tableView.adjustedContentInset
                } else {
                    contentInset = tableView.contentInset
                }
                
                let minContentOffset = -contentInset.top
                let maxContentOffset = tableView.contentSize.height - tableView.bounds.height + contentInset.bottom
                
                tableView.contentOffset.y = min(tableView.contentOffset.y, maxContentOffset)
                tableView.contentOffset.y = max(tableView.contentOffset.y, minContentOffset)
                
                snapshot_updatePosition()
                destinationRow_update()
            }
        }
        
        autoScroll_lastTImeStap = displayLink.timestamp
    }
}
